package com.knife.news.logic.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import com.knife.news.logic.TypeService;
import com.knife.news.logic.UserService;
import com.knife.news.object.Type;
import com.knife.news.object.User;
import com.knife.util.CommUtil;

public class TypeServiceImpl extends DAOSupportService implements TypeService {
	private static TypeServiceImpl typedao = new TypeServiceImpl();
	private UserService userDAO = UserServiceImpl.getInstance();
	private FlowServiceImpl flowDao = FlowServiceImpl.getInstance();
	public static TypeServiceImpl getInstance() {
		return typedao;
	}

	public String saveType(Type type) {
		com.knife.news.model.Type atype=new com.knife.news.model.Type();
		type.setId(atype.getId());
		atype.setType(type);
		if(this.dao.save(atype)){
			return atype.getId();
		}else{
			return "";
		}
	}

	public boolean updateType(Type type) {
		com.knife.news.model.Type atype=new com.knife.news.model.Type();
		atype.setType(type);
		return this.dao.update(atype);
	}

	public boolean delType(Type type) {
		dao.execute("delete from k_news where k_type='"+type.getId()+"'");
		dao.execute("update k_type set k_order=k_order-1 where k_parent='"+type.getParent()+"' and k_order>"+type.getOrder());
		com.knife.news.model.Type atype=new com.knife.news.model.Type();
		atype.setType(type);
		return this.dao.del(atype);
	}
	
	/*public List<com.knife.news.object.Type> getAllTypes(int display){
		return getAllTypes("",display);
	}*/
	
	public int getSum(int display,String parentid,String tree_id){
		int sum=0;
		String sql = "select count(*) from k_type where id!=''";
		Collection<Object> paras=new ArrayList<Object>();
		if(display >= 0) {
			paras.add(display);
			sql += " and k_display=?";
		}
		if(parentid.length()>0){
			paras.add(parentid);
			sql += " and k_parent=?";
		}
		if(tree_id.length()>0){
			paras.add(tree_id);
			sql += " and k_tree_id=?";
		}
		sum=Integer.parseInt(this.dao.uniqueResult(sql,paras).toString());
		return sum;
	}
	
	public List<Type> getTypes(int display) {
		return getAllTypes("",display);
	}
	
	public List<Type> getTypesByTree(String tree,int display){
		String sql = "id!=''";
		Collection<Object> paras=new ArrayList<Object>();
		paras.add(tree);
		sql += " and k_tree=?";
		if(display >= 0) {
			paras.add(display);
			sql += " and k_display=?";
		}
		sql += " order by length(k_order),k_order";
		return changeListType(this.dao.query(com.knife.news.model.Type.class, sql,paras));
	}
	
	public List<Type> getAllTypes(int display) {
		String sql = "id!=''";
		Collection<Object> paras=new ArrayList<Object>();
		if(display >= 0) {
			paras.add(display);
			sql += " and k_display=?";
		}
		sql += " order by length(k_order),k_order";
		return changeListType(this.dao.query(com.knife.news.model.Type.class, sql,paras));
	}
	
	public List<Type> getAllTypes(String siteid) {
		String sql = "id!=''";
		Collection<Object> paras=new ArrayList<Object>();
		if(siteid.length()>0) {
			paras.add(siteid);
			sql += " and k_site=?";
		}
		sql += " order by length(k_order),k_order";
		return changeListType(this.dao.query(com.knife.news.model.Type.class, sql,paras));
	}
	
	public List<Type> getAllTypes(String tree_id,int display){
		return getAllTypes("", tree_id, display);
	}
	
	public List<Type> getAllTypes(String siteid,String tree_id,int display) {
		String sql = "id!=''";
		Collection<Object> paras=new ArrayList<Object>();
		if(siteid.length()>0){
			paras.add(siteid);
			sql += " and k_site=?";
		}
		if(tree_id.length()>0){
			paras.add(tree_id);
			sql += " and k_tree_id=?";
		}
		if(display >= 0) {
			paras.add(display);
			sql += " and k_display=?";
		}
		sql += " order by length(k_order),k_order";
		return changeListType(this.dao.query(com.knife.news.model.Type.class, sql,paras));
	}

	public List<com.knife.news.object.Type> getAllTreeTypes(String tree_id,int display) {
		String sql = "id!=''";
		Collection<Object> paras=new ArrayList<Object>();
		paras.add(tree_id);
		sql += " and k_tree_id=?";
		if(display >= 0) {
			paras.add(display);
			sql += " and k_display=?";
		}
		sql += " order by length(k_order),k_order";
		return changeListType(this.dao.query(com.knife.news.model.Type.class, sql,paras));
	}
	
	public List<Type> getAllRightTypes(String userid){
		String sql = "";
		Collection<Object> paras=new ArrayList<Object>();
		paras.add(userid);
		sql = "id!='' and k_admin like '%'||?||',%' order by length(k_order),k_order";
		//List<com.knife.news.model.Type> types;
		return changeListType(this.dao.query(com.knife.news.model.Type.class, sql,paras));
	}
	
	public List<Type> getRootTypes(String sid,int display){
		return getSubTypesById(sid,"0",display);
	}

	public Type getTypeById(String id) {
		try{
			com.knife.news.model.Type atype = (com.knife.news.model.Type) this.dao.get(com.knife.news.model.Type.class, id);
			Type btype = new Type(atype);
			return btype;
		}catch(Exception e){
			return null;
		}
	}
	
	public com.knife.news.model.Type getModelTypeById(String id){
		try{
			com.knife.news.model.Type atype = (com.knife.news.model.Type) this.dao.get(com.knife.news.model.Type.class, id);
			return atype;
		}catch(Exception e){
			return null;
		}
	}
	public Type getTypeByName(String name) {
		Collection<Object> paras=new ArrayList<Object>();
		paras.add(name);
		String id=(String)this.dao.uniqueResult("select id from k_type where k_name=? order by length(k_parent),k_parent",paras);
		Type btype = new Type((com.knife.news.model.Type) this.dao.get(com.knife.news.model.Type.class, id));
		return btype;
	}
	
	public List<Type> getTypesByTemplate(String template) {
		Collection<Object> paras=new ArrayList<Object>();
		paras.add(template);
		paras.add(template);
		String sql="k_type_template=? or k_news_template=?";
		return changeListType(this.dao.query(com.knife.news.model.Type.class, sql,paras));
	}

	public List<Type> getTypesBySql(String sql) {
		return changeListType(this.dao.query(com.knife.news.model.Type.class, sql));
	}

	public List<com.knife.news.object.Type> getTypesBySql(String sql, Collection<Object> paras, int begin, int end) {
		return changeListType(this.dao.query(com.knife.news.model.Type.class, sql, paras, begin, end));
	}

	public List<Type> getSubTypesById(String parentid) {
		return this.getSubTypesById(parentid, -1);
	}
	
	public List<Type> getSubTypesById(String parentid,int display) {
		return this.getSubTypesById("",parentid, display,"","");
	}
	
	public List<Type> getSubTypesById(String siteid,String parentid,int display) {
		return this.getSubTypesById(siteid,parentid, display,"","");
	}

	public List<Type> getSubTypesById(String parentid,int display,String userid,String tree_id) {
		return this.getSubTypesById("",parentid, display,userid,tree_id);
	}
	
	public List<Type> getSubTypesById(String siteid,String parentid,int display,String userid,String tree_id) {
		String sql = "1=1";
		Collection<Object> paras=new ArrayList<Object>();
		if(siteid.length()>0){
			paras.add(siteid);
			sql += " and k_site=?";
		}
		if(parentid.length()>0){
			if(parentid.equals("0")){
				if(userid.length()<=0){
					sql += " and (k_parent='0' or k_parent='' or k_parent is null)";
				}
			}else{
				paras.add(parentid);
				sql += " and k_parent=?";
			}
		}
		if (display>=0) {
			paras.add(display);
			sql += " and k_display=?";
		}
		if(userid.length()>0){
			if(!userid.equals("0")){
				User auser=userDAO.getUserById(userid);
				if(auser!=null){
					if(auser.getPopedom()==0){
						sql += " and k_admin like '%" + userid + ",%'";
					}else if(auser.getPopedom()==1){
						sql += " and k_audit like '%" + userid + ",%'";
					}
				}
			}
		}
		if(tree_id.length()>0){
			paras.add(tree_id);
			sql += " and k_tree_id=?";
		}else{
			sql += " and (k_tree_id is null or k_tree_id='')";
		}
		sql += " order by length(k_order),k_order";
		//System.out.println("组装的SQL:"+sql);
		return changeListType(this.dao.query(com.knife.news.model.Type.class,sql,paras));
	}
	
	//jlm
	public List<Type> getTaskTypesById(String siteid,String parentid,int display,String userid,String tree_id) {
		String sql = "1=1";
		Collection<Object> paras=new ArrayList<Object>();
		if(siteid.length()>0){
			paras.add(siteid);
			sql += " and k_site=?";
		}
		if (display>=0) {
			paras.add(display);
			sql += " and k_display=?";
		}
		 //flow  
		try {
			if (siteid.length() > 0 && userid.length() > 0 && !userid.equals("0") ) {
				Collection<Object> pa=new ArrayList<Object>();
				String sqlflow="";
//				pa.add(atype.getFlow());
				pa.add(siteid);
				sqlflow="k_site=? and k_status='1'";
				if(flowDao.getFlowBySql(sqlflow, pa, 0, -1).size()>0 && userDAO.getUserById(userid).getPopedom()<2 ){
//					paras.add(atype.getFlow());
					paras.add(siteid);
					String subsql="";
					sql+="and k_flow in (select id from k_flow where k_site=? and k_status='1')";
					/*
					subsql= " and (k_flow in(select id from k_flow where k_site=? and k_status='1')";
					if (userDAO.getUserById(userid) != null) {
						if (userDAO.getUserById(userid).getPopedom() == 0) {
							sql += subsql+" or k_admin like '%" + userid + ",%')";
						} else if (userDAO.getUserById(userid).getPopedom() == 1) {
							sql += subsql+" or k_audit like '%" + userid + ",%')";
						}
					}
				*/
				}
			
			}// end flow
		}catch(Exception e){ e.getStackTrace();}
		if(tree_id.length()>0){
			paras.add(tree_id);
			sql += " and k_tree_id=?";
		}else{
			sql += " and (k_tree_id is null or k_tree_id='')";
		}
		sql += " order by length(k_order),k_order";
		//System.out.println("组装的SQL:"+sql);
		List<Type> test = new ArrayList<Type>();
		return changeListType(this.dao.query(com.knife.news.model.Type.class,sql,paras)); 
	}
	
	public String getAllSubTypesId(String parentid,int display){
		return getAllSubTypesId("",parentid,display);
	}
	
	public String getAllSubTypesId(String siteid,String parentid,int display){
		StringBuffer buf = new StringBuffer();
		//buf.append("'"+parentid+"'");
		Type thistype=getTypeById(parentid);
		String sql = "id!=''";
		String thistreeid="";
		if(CommUtil.null2String(thistype.getTree()).length()>0){	
			thistreeid = thistype.getTree();
		}
		Collection<Object> paras=new ArrayList<Object>();
		if(siteid.length()>0){
			paras.add(siteid);
			sql += " and k_site=?";
		}
		if(parentid.length()>0){
			paras.add(parentid);
			sql += " and (k_parent=?";
			if(thistreeid.length()>0){
				paras.add(thistreeid);
				sql += " or k_tree_id=?";
			}
			sql+=")";
		}
		if(display >= 0) {
			paras.add(display);
			sql += " and k_display=?";
		}
		List<Object> types=this.dao.query(com.knife.news.model.Type.class, sql, paras);
		for(Object atype : types){
			com.knife.news.model.Type aType=(com.knife.news.model.Type)atype;
			buf.append(",'"+aType.getId()+"'");
			Type tobj =  new Type(aType);
			if(!tobj.isLeave() || CommUtil.null2String(tobj.getTree()).length()>0){
				buf.append(getAllSubTypesId(tobj.getId(),display));
			}
		}
		/*
		if(this.getTypeById(parentid).getTree()!=null){
			List<com.knife.news.object.Type> subTreeTypes = this.getAllTreeTypes(thistreeid,1);
			for(Object btype : subTreeTypes){
				com.knife.news.object.Type bType =(com.knife.news.object.Type)btype;
				if(buf.indexOf("'"+bType.getId()+"'")<=0){
					buf.append(",'"+bType.getId()+"'");
				}
			}
		}
		List<com.knife.news.object.Type> subTypes = this.getSubTypesById(parentid);
		if(subTypes!=null){
			for(Object atype : subTypes){
				com.knife.news.object.Type aType =(com.knife.news.object.Type)atype;
				if(aType.getTree()!=null){
					List<com.knife.news.object.Type> subTreeTypes = this.getAllTreeTypes(aType.getTree(),1);
					for(Object btype : subTreeTypes){
						com.knife.news.object.Type bType =(com.knife.news.object.Type)btype;
						if(buf.indexOf("'"+bType.getId()+"'")<=0){
							buf.append(",'"+bType.getId()+"'");
						}
					}
				}
				if(aType.getId()!=null){
					//subtypesid+=","+this.getAllSubTypesId(aType.getId());
					//subtypesid+=","+this.getAllSubTypesId(aType.getId());
					buf.append(","+this.getAllSubTypesId(aType.getId()));
				}
			}
		}
		//return subtypesid;
		*/
		return buf.toString();
	}
	
	public List<Type> getAllSubTypesById(String cid,int display){
		String subtypeids=getAllSubTypesId("",cid,display);
		//System.out.println("aaaaaaaaaaa subtypes id:"+subtypeids);
		String[] ids=subtypeids.split(",");
		List<Type> stypes=new ArrayList<Type>();
		for(String id:ids){
			if(id.length()>0){
				id=id.replace("'", "");
				Type atype=this.getTypeById(id);
				if(atype!=null){
					stypes.add(atype);
				}
			}
		}
		if(stypes.size()>0){
			return stypes;
		}else{
			return null;
		}
	}
	
	public List<Type> getRightSubTypesById(String parentid, String userid) {
		return getSubTypesById(parentid,1,userid, "");
	}
	
	public List<Type> getAllParentTypesById(String cid){
		List<Type> ptypes=new ArrayList<Type>();
		Type type=getTypeById(cid);
		if(type!=null){
			if (!type.getParent().equals("0")) {
				ptypes.add(type.getParentType());
				List<Type> restptypes=getAllParentTypesById(type.getParent());
				if(restptypes.size()>0){
					ptypes.addAll(restptypes);
				}
			}
		}
		return ptypes;
	}
	
	public List<Type> getTreeTypesByTypeID(String id,int display){
		//News anews=newsDAO.getNewsById(id);
		com.knife.news.object.Type atype=this.getTypeById(id);
		String tree_id="";
		if(atype!=null){
			tree_id=CommUtil.null2String(atype.getTree());
		}
		if(tree_id.length()>0){
			return getAllTypes(tree_id,display);
		}else{
			return null;
		}
	}

	public boolean hasRightUser(String id, String userid,int pop) {
		if (id.equals("")) {
			id = "0";
		}
		if (userid.equals("")) {
			userid = "0";
		}
		if (id.length() > 0) {
			com.knife.news.model.Type atype = getModelTypeById(id);// 使用object.type会导致死循环，为了避开，选用model.type
			if (atype != null && atype.getFlow() != null
					&& atype.getFlow() != ""
					&& flowDao.getFlowById(atype.getFlow()) != null
					&& flowDao.getFlowById(atype.getFlow()).getStatus() == 1) {
				if (this.dao.uniqueResult("select * from k_type where id='"
						+ id + "'") != null) {
					return true;
				} else {
					return false;
				}
			} else {
				String column="k_admin";
				if(pop==0){
					column="k_admin";
				}else if(pop==1){
					column="k_audit";
				}
				if (this.dao.uniqueResult("select * from k_type where id='" + id
						+ "' and "+column+" like '%" + userid + ",%'") != null) {
					return true;
				} else {
					return false;
				}
			}
		} else {
			String column="k_admin";
			if(pop==0){
				column="k_admin";
			}else if(pop==1){
				column="k_audit";
			}
			if (this.dao.uniqueResult("select * from k_type where id='" + id
					+ "' and "+column+" like '%" + userid + ",%'") != null) {
				return true;
			} else {
				return false;
			}
		}
	}

	public void reOrderTypes(Type type) {
		if (type != null) {
			List<Type> types = new LinkedList<Type>();
			String sql = "k_parent='" + type.getParent() + "' and k_order>"
					+ type.getOrder() + " order by length(k_order),k_order";
			if (getTypesBySql(sql) != null) {
				types = getTypesBySql(sql);
			}
			for (Object atype : types) {
				//com.knife.news.model.Type btype = new com.knife.news.model.Type();
				Type btype = (Type) atype;
				//btype.setType((Type)atype);
				if (btype.getOrder() > 1) {
					btype.setOrder(btype.getOrder() - 1);
				}
				updateType(btype);
			}
		}
	}

	public void reArrange(String siteid,Type oldType, String parent,String treeid, int newOrder) {
		if (!parent.equals("")) {
			if (newOrder > 0) {
				List<Type> types = this.getSubTypesById(siteid,parent,-1,"",treeid);
				int maxOrder = types.size();
				if (newOrder > maxOrder) {
					newOrder = maxOrder;
				}
				int oldOrder = oldType.getOrder();
				String oldSite=CommUtil.null2String(oldType.getSite());
				if(siteid.equals(oldType.getSite()) || oldSite.length()==0){
					//System.out.println("获取到的频道数:"+maxOrder);
					Collection<Object> paras = new ArrayList<Object>();
					String sql="1=1";
					if(oldSite.length()>0){
						paras.add(oldSite);
						sql+=" and k_site=?";
					}
					if(treeid.length()>0){
						paras.add(treeid);
						sql+=" and k_tree_id=?";
					}
				if (!parent.equals(oldType.getParent())) {
					dao.execute("update k_type set k_order=k_order-1 where "+sql+" and k_parent='"+ oldType.getParent() +"' and k_order>"+ oldOrder,paras);
					dao.execute("update k_type set k_order=k_order+1 where "+sql+" and k_parent='"+ parent +"' and k_order>="+ newOrder,paras);
				} else {
					//System.out.println("获取到的频道数:"+maxOrder);
					if (oldOrder != newOrder) {
						types = changeListType(dao.query(com.knife.news.model.Type.class, sql, paras));
						maxOrder = types.size();
						if (newOrder > maxOrder) {
							newOrder = maxOrder;
						}
						if (oldOrder < newOrder) {
							
							dao
									.execute("update k_type set k_order=k_order-1 where "+sql+" and k_parent='"
											+ parent
											+ "' and k_order<="
											+ newOrder
											+ " and k_order>="
											+ oldOrder,paras);
						} else {
							dao
									.execute("update k_type set k_order=k_order+1 where "+sql+" and k_parent='"
											+ parent
											+ "' and k_order>="
											+ newOrder
											+ " and k_order<="
											+ oldOrder,paras);
						}
					}
				}
				oldType.setParent(parent);
				oldType.setOrder(newOrder);
				com.knife.news.model.Type atype=new com.knife.news.model.Type();
				atype.setType(oldType);
				dao.update(atype);
				}
			}
		}
	}
	
	public List<Type> changeListType(List<Object> objs){
		List<Type> results = new ArrayList<Type>();
		if(objs!=null){
			for (Object newobj : objs) {
				com.knife.news.model.Type robj = (com.knife.news.model.Type) newobj;
				Type tobj =  new Type(robj);
				results.add(tobj);
			}
		}
		return results;	
	}
	
	public List<Type> md2obj(List<com.knife.news.model.Type> types){
		List<Type> results = new ArrayList<Type>();
		results.clear();
		if(types!=null){
			for (Object atype : types) {
				com.knife.news.model.Type atp = (com.knife.news.model.Type) atype;
				Type btype = new Type(atp);
				results.add(btype);
			}
		}
		return results;
	}
}